package com.lushu.chapitre1.graphics.animation
{
	import com.lushu.graphics.engine.animation.AnimatedBitmap;
	import com.lushu.palettes.BodyPaletteData;
	import com.lushu.palettes.EyePaletteData;
	import com.lushu.palettes.HairPaletteData;
	import com.lushu.palettes.Palette;
import com.sfdk.graphics.engine.animation.AnimatedBitmap;

import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;

	public class UserAnimatedBitmap extends AnimatedBitmap
	{
		private var _hairPalette : Palette;
		private var _bodyPalette : Palette;
		private var _eyePalette : Palette;
		
		public function UserAnimatedBitmap(animatedBitmap : AnimatedBitmap)
		{
			super();
			_animationTile = animatedBitmap.animationTile;
			_animationLength = animatedBitmap.animationLength;
			_animationData = animatedBitmap.animationData;
			_isLoaded = true;
		}
		
		public function setPalettes(bodyPalette : Palette, hairPalette : Palette, eyePalette : Palette) : void
		{
			_hairPalette = hairPalette;
			_bodyPalette = bodyPalette;
			_eyePalette = eyePalette;
			var totalPalette : Palette = _bodyPalette.add(_hairPalette.add(_eyePalette));
			
			var bitmapData : BitmapData;
			var paletteRectangle : Rectangle = new Rectangle();
			var basePoint : Point = new Point();
			for each(bitmapData in _animationTile)
			{
				paletteRectangle.width = bitmapData.width;
				paletteRectangle.height = bitmapData.height;
				bitmapData.paletteMap(bitmapData, paletteRectangle, basePoint, totalPalette.red, totalPalette.green, totalPalette.blue);
			}
		}
		
		public function add(animatedBitmap : AnimatedBitmap) : void
		{
			// The add is based on the animationData to update the tile accordingly
			var actionChooserDP : Vector.<String> = new <String>["Statique", "Marche"];
			var faceChooserDP : Vector.<String> = new <String>["Face", "Dos", "Gauche", "Droite"];
			var currFace : String;
			var currAction : String;
			var addedActionArray : Array;
			var originalActionArray : Array;
			var mapping : Dictionary = new Dictionary();
			var prevMapping : Object;
			var stateToCreate : Dictionary = new Dictionary();
			var maxId : int = _animationTile.length;
			var i : int;
			var diffXOffset : int;
			var diffYOffset : int;
			for each(currFace in faceChooserDP)
			{
				for each(currAction in actionChooserDP)
				{
					addedActionArray = animatedBitmap.animationData[currAction+"_"+currFace];
					originalActionArray = _animationData[currAction+"_"+currFace];
					for(i = 0; i < addedActionArray.length; i++)
					{
						diffXOffset = addedActionArray[i].xOffset - originalActionArray[i].xOffset;
						diffYOffset = addedActionArray[i].yOffset - originalActionArray[i].yOffset;
						
						// We need to backReference all change made to the offset to the animation info
						originalActionArray[i].xOffset += diffXOffset;
						originalActionArray[i].yOffset += diffYOffset;
						
						if(mapping[originalActionArray[i].id] != null)
						{
							prevMapping = mapping[originalActionArray[i].id];
							if(prevMapping.id != addedActionArray[i].id || prevMapping.xOffset != diffXOffset || prevMapping.yOffset != diffYOffset)
							{
								stateToCreate[maxId] = originalActionArray[i].id;
								mapping[maxId] = {id : addedActionArray[i].id, xOffset : diffXOffset, yOffset : diffYOffset}
								originalActionArray[i].id = maxId;
								maxId++;
							}
						}
						else
						{
							mapping[originalActionArray[i].id] = {id : addedActionArray[i].id, xOffset : diffXOffset, yOffset : diffYOffset};
						}
					}
				}
			}
			
			// First create the missing ID
			var newId : String;
			var prevId : int;
			var prevBitmap : BitmapData;
			for (newId in stateToCreate)
			{
				prevId = stateToCreate[newId];
				prevBitmap = _animationTile[prevId] as BitmapData;
				_animationTile[newId] = prevBitmap.clone();
			}
			
			// Now merge the bitmap based on the info we have
			var addedId : Object;
			var addedBitmap : BitmapData;
			var newBitmap : BitmapData;
			var copyRect : Rectangle = new Rectangle();
			var copyPoint : Point = new Point();
			var initXOffset : int;
			var initYOffset : int;
			var addXOffset : int;
			var addYOffset : int;
			var newWidth : int;
			var newHeight : int;
			for (newId in mapping)
			{
				addedId = mapping[newId];
				prevBitmap = _animationTile[newId] as BitmapData;
				addedBitmap = animatedBitmap.animationTile[addedId.id] as BitmapData;
				
				newWidth = prevBitmap.width;
				newHeight = prevBitmap.height;
				
				if(addedId.yOffset < 0)
				{
					initYOffset = -addedId.yOffset;
					addYOffset = 0;
					newHeight -= addedId.yOffset
				}
				else
				{
					initYOffset = 0;
					addYOffset = addedId.yOffset;
				}
				if(addedId.xOffset < 0)
				{
					initXOffset = -addedId.xOffset;
					addXOffset = 0;
					newWidth -= addedId.xOffset
				}
				else
				{
					initXOffset = 0;
					addXOffset = addedId.xOffset;
				}
				
				if( addedId.yOffset < 0  && addedBitmap.height > newHeight)
				{
					newHeight += addedBitmap.height - newHeight;
				}
				else if((addedId.yOffset + addedBitmap.height) > newHeight)
				{
					newHeight += ((addedId.yOffset + addedBitmap.height) - newHeight)
				}
				
				if( addedId.xOffset < 0  && addedBitmap.width > newWidth)
				{
					newWidth += addedBitmap.width - newWidth;
				}
				else if((addedId.xOffset + addedBitmap.width) > newWidth)
				{
					newWidth += ((addedId.xOffset + addedBitmap.width) - newWidth)
				}
					
				
				
				// we need to extend the bitmap by the difference
				newBitmap = new BitmapData(newWidth , newHeight, true, 0);
				copyRect.width = prevBitmap.width;
				copyRect.height = prevBitmap.height;
				copyPoint.x = initXOffset;
				copyPoint.y = initYOffset;
				newBitmap.copyPixels(prevBitmap, copyRect, copyPoint, null, copyPoint, true);
				
				copyRect.width = addedBitmap.width;
				copyRect.height = addedBitmap.height;
				copyPoint.x = addXOffset;
				copyPoint.y = addYOffset;
				newBitmap.copyPixels(addedBitmap, copyRect, copyPoint, null, copyPoint, true);

				_animationTile[newId] = newBitmap;
			}
			_animationLength = _animationTile.length;
		}
	}
}